<?php
/**
 * @class StreamModel
 * @name 直播推流及获取相关信息model
 * @author martinsun syh@sunyonghong.com
 */
namespace app\stream\model;
use \think\Model;

class Stream extends Model {
	//定义当前表
	protected $tableName = 'stream';
	//定义表的字段信息
	protected $fields = ['id', 'uid', 'stream_id', 'stream_title', 'stream_icon', 'stream_hub', 'status', 'location', 'disable_time', 'airtime', 'last_airtime','is_del'];
	//定义需要填充的数据,调用validateData方法进行填充
	protected $auto = [];
	/**
	 * @name 根据UID获得单个stream_id信息
	 * @access public
	 * @param int|string $uid 用户的UID
	 * @return string stream_id
	 */
	public function getStreamId($uid = 0) {
	    $map['uid'] = $uid;
        $map['stream_hub'] = model('admin/Config')->getConfigValue(['type'=>'stream','key'=>'stream_service'],'hub_name');
        return $this->where($map)->order('id desc')->getField('stream_id');
	}
	/**
	 * @name 根据UID获得单个stream_title信息
	 * @access public
	 * @param int|string $uid 用户的UID
	 * @return string stream_id
	 */
	public function getStreamTitle($uid = '') {
	    $map['uid'] = $uid;
        $map['stream_hub'] = model('admin/Config')->getConfigValue(['type'=>'stream','key'=>'stream_service'],'hub_name');
		return $this->where($map)->order('id desc')->getField('stream_title');
	}
	/**
	 * @name 通过房间号取得主播uid
	 * @access public
	 * @param string $stream_id 直播间的ID
	 * @return string 用户UID
	 */
	public function getUidByStream($stream_id = '') {
		return $this->getFieldByStreamId($stream_id, 'uid');
	}
	/**
	 * @name 根据UID获取主播的房间状态
	 * @access public
	 * @param int $uid 用户的UID
	 * @return int 0:禁播  1:正在直播  2:未直播
	 */
	public function getStreamStatus($uid = 0) {
	    $map['uid'] = $uid;
        $map['stream_hub'] = model('admin/Config')->getConfigValue(['type'=>'stream','key'=>'stream_service'],'hub_name');
		return (int) $this->where($map)->order('id desc')->getField('status');
	}
	/**
	 * @name 通过房间号取得直播状态
	 * @access public
	 * @param int $uid 用户的UID
	 * @return int 0:禁播  1:正在直播  2:未直播
	 */
	public function getStatusByStream($stream_id = 0) {
		return (int) $this->getFieldByStreamId($stream_id, 'status');
	}
	/**
	 * @name 添加本地单条数据
	 * @access public
	 * @param array $data 添加的数据数组
	 * @return int 数据表ID
	 */
	public function add($data = []) {
		if (is_string($data)) {
			$data = explode(',', $data);
		} else if (!is_array($data)) {
			return false;
		}
		$data = self::validateData($data, true);
		return parent::add($data);
	}
	/**
	 * @name 本地数据验证(过滤和自动填充数据)
	 * @access protected
	 * @param array $data 验证的数据数组
	 * @param boolean $auto 是否自动填充数据
	 * @return array 验证后的数据
	 */
	protected function validateData($data = [], $auto = false) {
		if (!$data || !is_array($data)) {
			return false;
		}

		$res = [];
		$this->fields = $this->fields ?: $this->getFields();
		foreach ($data as $k => $v) {
			in_array($k, $this->fields) && $res[$k] = $v;
		}
		if ($auto && !empty($this->auto)) {
			return array_merge($res, $this->auto);
		}
		return $res;
	}
	/**
	 * @name 获取本地的stream相关信息
	 * @access public
	 * @param int $uid 用户的UID
	 * @param array $field 获取指定的字段信息
	 * @return array 数组数据信息
	 */
	public function getstreamInfo($uid = 0, $field = [],$is_check = false) {
		if (!$uid) {
			return false;
		}
        $map['stream_hub'] = model('admin/Config')->getConfigValue(['type'=>'stream','key'=>'stream_service'],'hub_name');
		$map['uid'] = (int) ($uid);
        //检测并更新禁播状态
        if($is_check === false)$this->getDisable($uid);
		if (empty($field)) {
			return $this->where($map)->order('id desc')->find();
		} else {
			return $this->where($map)->field($field)->order('id desc')->find();
		}
	}
	/**
	 * @name 更新直播间数据信息
	 * @access public
	 * @param array $data 需要更新的数据
	 * @param array $map 更新的条件
	 * @return boolean 更新的结果
	 */
	public function update($data = [], $map = []) {
		if (empty($data) || !$map) {
			return false;
		}
        $map['stream_hub'] = model('admin/Config')->getConfigValue(['type'=>'stream','key'=>'stream_service'],'hub_name');
		$res = $this->where($map)->save($data);
		if ($res) {
			S('stream_array_' . $map['uid'], null);
			S('stream_objec_' . $map['uid'], null);
		}
		return (boolean) $res;
	}
	/**
	 * @name 单独更新封面图
	 */
	public function updateIcon($data = []) {
		return self::update(['stream_icon' => $data['stream_icon']], ['uid' => $data['uid']]);
	}
	/**
	 * @name 添加主播的临时数据
	 * @access public
	 * @param int $uid 用户uid
	 * @return boolean 添加的结果
	 */
	public function addAnchorTmp($uid = 0) {
		if (!(int) $uid) {
			return false;
		}

		// $tmp = M('anchor_tmp');
		$tmp = model('stream/AnchorTmp');
		if ($tmp->where(['uid' =>  (int) $uid])->count() > 0 || $tmp->add(['uid' => (int) $uid])) {
			return true;
		}
		return false;
	}
	/**
	 * @name 结束直播获取放回数据
	 * @access public
	 * @param int $uid 用户UID
	 * @param boolean $is_own 是否获取自己的
	 * @return array 数据结果,UID非法没有信息将返回空数组
	 */
	public function getEndLiveData($uid = 0, $is_own = false, $count = 4) {
		$data = [];
		if ($is_own == true && !$uid) {
			return $data;
		}

		$tmp_table = M('anchor_tmp');
		if ($is_own === true) {
			$data = $tmp_table->field(['gold', 'zan_count', 'view_count'])->where('uid=' . (int) $uid)->find();
			// $data['view_count'] = self::getOnlineCount($uid, true);
			if (!$data) {
				$data = ['gold' => 0, 'zan_count' => 0, 'view_count' => 0];
			} else {
				array_walk($data, create_function('&$v,$k', '$v = intval($v);'));
				//更新数据
				self::updateUserData($uid, $data);
			}
		} else {
			$count = $count >= 0 ? $count : 4;
			$data['uids'] = self::getRandUids($count);
			$data['view_count'] = self::getOnlineCount($uid);
		}
		return $data;
	}
	public function getEndLiveDataDoNotClear ($uid = 0, $is_own = false, $count = 4)
    {
        $data = [];
        if ($is_own == true && !$uid) {
            return $data;
        }

        $tmp_table = M('anchor_tmp');
        if ($is_own === true) {
            $data = $tmp_table->field(['gold', 'zan_count'])->where('uid=' . (int) $uid)->find();
            $data['view_count'] = self::getOnlineCount($uid, true);
            if (!$data) {
                $data = ['gold' => 0, 'zan_count' => 0, 'view_count' => 0];
            } else {
                array_walk($data, create_function('&$v,$k', '$v = intval($v);'));
                //更新数据
                // self::updateUserData($uid, $data);
            }
        } else {
            $count = $count >= 0 ? $count : 4;
            $data['uids'] = self::getRandUids($count);
            $data['view_count'] = self::getOnlineCount($uid);
        }
        return $data;
    }
	/**
	 * @name 更新主播的数据
	 * @access public
	 * @param int $uid 用户UID
	 * @param array $data 需要更新的字段信息 以二维数组传递,['字段'=>值]
	 * @return boolean 更改完成后是否成功删除临时表数据
	 */
	public function updateUserData($uid = 0, $data = []) {
		if (!$data || !is_array($data)) {
			//$data = M('anchor_tmp')->field(['gold','zan_count','view_count'])->where('uid='.(int)$uid)->find();
			return true;
		}
        $airtime = (int)$this->getFieldByUid($uid, 'airtime');
        if($airtime > 0){
		  $airtime = NOW_TIME - $airtime;
          $data['live_time'] = (int) (floor($airtime / 60));
        }else{
          $data['live_time'] = 0;
        }
		
		$data['zan_remain'] = $data['zan_count'];
		$user_data_model = D('open/UserData');
		foreach ($data as $k => $v) {
			$user_data_model->dataInco($uid, $k, $v);
		}
		$re = M('anchor_tmp')->where(['uid' => $uid])->delete();
		return $re ? true : false;
	}
	/**
	 * @name 随机查询主播
	 * @access public
	 * @param int $limit 获取的数量
	 * @return array $uids 主播UID
	 */
	public function getRandUids($limit = 4) {
		$uids = [];
		$not_uid = 0;
		for ($i = 0; $i < $limit; $i++) {
			$table = '__PREFIX__stream';
			$sql = 'SELECT uid FROM `' . $table . '` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `' . $table . '`)-(SELECT MIN(id) FROM `' . $table . '`))';
			$sql .= '+(SELECT MIN(id) FROM `' . $table . '`)) AS id) AS t2 WHERE t1.id >= t2.id and status = 1 and uid not in(' . $not_uid . ') ORDER BY t1.id LIMIT 1;';
			$re = $this->query($sql);
			if ($re) {
				array_push($uids, $re[0]['uid']);
				$not_uid .= ',' . $re[0]['uid'];
			}
		}
		if (empty($uids) && $this->where('status=1')->count() > 0) {
			$re = $this->where('status=1')->field('uid')->order('airtime desc')->limit($limit)->select();
			$uids = getSubByKey($re, 'uid');
		}
		return $uids;
	}
	/**
	 * @name 实时获取指定主播间的在线人数
	 * @access public
	 * @param int $uid 用户uid
	 * @param boolean $tmp 是否从临时表获取数据
	 * @return int 统计的结果数
	 */
	public function getOnlineCount($uid = 0, $tmp = false) {
		if (!$uid) {
			return 0;
		}

		if ($tmp === true) {
			//取缓存表的数据
			$count = M('anchor_tmp')->getFieldByUid($uid, 'view_count') ?: 0;
			//$multiple = C('online_math');
			//$multiple = $multiple ? $multiple : 1;
			//$count = (int) $count * $multiple;
            $count = (int)$count;
		} else {
			//取数据表的数据
			$count = M('user_data')->getFieldByUid($uid, 'view_count') ?: 0;
		}
		return $count;
	}
	/**
	 * @name 获取直播间列表
	 * @access public
	 * @param array $map 赛选条件
	 * @param string $order 排序方式
	 * @param int $limit 获取条数
	 * @return array 用户UID数组
	 */
	public function getList($map = [], $order = '', $limit = 10) {

		$where = $this->validateData($map);
        $where['stream_hub'] = model('admin/Config')->getConfigValue(['type'=>'stream','key'=>'stream_service'],'hub_name');
		$where['status'] = isset($map['status']) ? $map['status'] : 1;
		$uids = [];
		//排序方式取数据
        if($map['sex']){
            $subSql = model('open/User')->where(['sex' => $map['sex'],'uid'=>$where['uid']])->field('uid')->buildSql();
        }else{
            $subSql = model('open/User')->where(['uid'=>$where['uid']])->field('uid')->buildSql();
        }
        unset($where['uid']);
		if ($order == 'airtime') {
			$order = 'airtime desc';
            if($subSql){
                $sql = $this->where($where)->alias('s')->join($subSql.' u','u.uid = s.uid','RIGHT')->order($order)->buildSql();
                $sql = substr($sql,1,-1);
                $res = $this->findPageBySql($sql,null,$limit);
            }else{
                $res = $this->field(['uid'])->where($where)->order($order)->findPage();
            }
			if ($res['gtLastPage']) {
				return [];
			}
            if ($res['data']) {
			 $uids = getSubByKey($res['data'], 'uid');
            }
		} else {
			$order = 'view_count desc';
            if($subSql){
                $sql = $this->where($where)->alias('s')->join($subSql.' u','u.uid = s.uid','RIGHT')->buildSql();
                $sql = substr($sql,1,-1);
                $res = $this->findPageBySql($sql,null,$limit);
            }else{
                $res = $this->field(['uid'])->where($where)->findPage($limit);
            }
			if ($res['gtLastPage']) {
				return [];
			}
			if ($res['data']) {
				//对数据进行实时排序
				$res['data'] = getSubByKey($res['data'], 'uid');
				$list = M('anchor_tmp')->field('uid,view_count')->where(['uid' => ['in', $res['data']]])->order($order)->select();
				$list_uid = getSubByKey($list, 'uid');
				$uids = array_unique(array_merge($list_uid, $res['data']));
			}
		}
		return $uids;
	}
	/**
	 * @name 检测与更新主播禁播状况
	 * @access public
	 * @param int $uid 用户UID
	 * @return array or int
	 *  如果返回数组,表示用户已经被禁播,数据data中的time可以看到禁播的截止时间
	 *  如果返回的是整形  1代表正常  2代表禁播的时间已经过了,需要更新流的禁播状态
	 */
	public function getDisable($uid = 0) {
		//非法用户
		if (!$uid) {
			return getApiErrorCode('40007');
		}

		$info = $this->getstreamInfo($uid, ['status', 'disable_time'],true);
		if ($info['status'] == '0') {
			if ($info['disable_time'] == '0') {
				$return = getApiErrorCode('60000');
				$return['time'] = '2099年12月31日 23时59分';
				return ['code' => '00000', 'data' => $return];
			} elseif ($info['disable_time'] > NOW_TIME) {
				$return = getApiErrorCode('60000');
				$return['time'] = date('Y年m月d日 H时i分', $info['disable_time']+60);
				//$return['data'] = getTimediff(NOW_TIME,$info['disable_time']);
				return ['code' => '00000', 'data' => $return];
			} else {
				//禁言时间已过
				$update['disable_time'] = 0;
				$update['status'] = 2;
				$this->update($update, ['uid' => $uid]);
				return 2;
			}
		}
		return 1;
	}
	/**
	 * @name 搜索
	 * @access public
	 * @param array $map搜索的条件
	 * @param int $limit 数据的条数 default:10
	 * @return array 用户的UID数组
	 */
	public function getSearch($map = [], $limit = 10, $order = 'airtime desc') {
		//数据过滤
		$where = $this->validateData($map);
		$res = $this->field('uid')->where($where)->order($order)->findPage($limit);
		//echo $this->getLastSql();exit;
		//数据校验
		if ($res['gtLastPage'] || !$res['data']) {
			return [];
		}
		//返回数据
		$uids = getSubByKey($res['data'], 'uid');
		return $uids;
	}
	/**
	 * @name 添加主播的收益到临时表
	 * @access public
	 * @param string $field 字段
	 * @param string $value 值
	 * @param int $uid 用户UID
	 * @return boolean 添加结果
	 */
	public function addInc($field = '', $value = '', $uid = 0) {
		if (!$uid) {
			return false;
		}
		return (boolean) M('anchor_tmp')->where('uid=' . (int) $uid)->setInc($field, $value);
	}
    
    /**
     * @name 获取主播的直播状态
     */
    public function getStatusByUsid($usid = ''){
        $res = [];
        if($usid){
            $usid = !is_array($usid) ? explode(',',$usid) : (array)$usid;
            $userModel = model('open/User');
            foreach($usid as $u){
                if(!$u) continue;
                $uid = $userModel->getUidByUsid($u);
                if($uid){
                    $status = $this->getStreamStatus($uid) === 1 ? 1 : 0;
                }else{
                    $status = 0;
                }
                $item = [
                    'usid' => $u,
                    'status' => $status,
                    'uid' => $uid
                ];
                array_push($res,$item);
            }
        }
        return $res;
    }
    /**
     * @name 后台直播间列表信息
     */
     public function adminGetList($map = [],$order = '',$limit = 10){
        $map['stream_hub'] = model('admin/Config')->getConfigValue(['type'=>'stream','key'=>'stream_service'],'hub_name');
        if($map['uname'] || $map['sex']){
            $map['uname'] && $subMap['uname'] = $map['uname'];
            $map['sex'] && $subMap['sex'] = $map['sex'];
            $subSql = model('open/User')->where($subMap)->field('uid')->buildSql();
            unset($map['uname'],$map['sex']);
            $subSql = $this->where($map)->alias('s')->join($subSql.' u','u.uid = s.uid','RIGHT')->order($order)->buildSql();
        }else{
            unset($map['uname'],$map['sex']);
            $subSql = $this->where($map)->order($order)->buildSql();
        }
        $sql = substr($subSql,1,-1);;
        $list = $this->findPageBySql($sql,null,$limit);
        $user_model = model('open/User');
        $user_data_model = model('open/UserData');
        $stream_action = A('stream/Stream');
        foreach($list['data'] as &$v){
            $v['user'] = $user_model->getUserInfo($v['uid']);
            $v['user']['sex'] = $user_model->getUserSex($v['uid']);
            $v['user_data'] = $user_data_model->getUserAccount($v['uid']);
            if($v['status'] == 1){
                $v['stream_snapshot'] = $stream_action->getSnapshotByStreamId($v['stream_id']);
            }else{
                $v['stream_snapshot'] = '';
            }
            $v['view_count'] = $this->getOnlineCount($v['uid'],true);
        }
        return $list;
     }
    /**
     * @name 后台直播间列表信息
     */
     public function adminGetInfo($map = []){
        $map['stream_hub'] = model('admin/Config')->getConfigValue(['type'=>'stream','key'=>'stream_service'],'hub_name');
        $info = $this->where($map)->find();
        if($info){
            $stream_controller = A('stream/Stream');
            $info['user'] = model('open/User')->getUserInfo($info['uid']);
            $info['user']['sex'] = model('open/User')->getUserSex($info['uid']);
            $info['user_data'] = $this->getTmpeAccount($map['uid']);//model('open/UserData')->getUserAccount($info['uid']);
            $info['stream_snapshot'] = $stream_controller->getSnapshotByStreamId($info['stream_id']);
            $info['view_count'] = $this->getOnlineCount($info['uid'],true);
            if($info['status'] == 1){
                //正在直播,获取聊天室,获取播放地址
                $im = model('open/UserImAccount')->getConversation(['affix' => $info['stream_id'], 'type' => 2]);
                $info['im'] = $im;
                if ($im['cid'] > 0) {
                    $stream = $stream_controller->getStreamClass($info['uid']);
    				$info['playurls'] = $stream_controller->playUrls($stream);
    			}
            }
            if($info['status'] == 0 && $info['disable_time'] == 0){
                $info['disable_code'] = 0;//永久
            }elseif($info['status'] == 0){
                $info['disable_code'] = 2;//限时
            }else{
                $info['disable_code'] = 1;//解除禁播
            }
        }
        return $info ? object2array($info) : [];
     }
     /**
      * @name 获取临时统计数据
      */
     public function getTmpeAccount($uid = 0){
        return M('anchor_tmp')->field(['gold','zan_count','view_count'])->where('uid='.$uid)->find();
     }
}
